﻿using Mian.Model;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Diagnostics.Internal;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Transactions;

namespace Main.Repository
{
    public class Repository<T> : IRepository<T> where T : class, new()
    {
        private readonly ChatManangerContext _DBContext;
        public Repository(ChatManangerContext chatManangerContext)
        {
            _DBContext = chatManangerContext;
        }
        public bool Add(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                _DBContext.Set<T>().Add(t);
                int count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }

        public async Task<bool> AddAsync(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                _DBContext.Set<T>().Add(t);
                int count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
                return count > 0;
            }
        }

        public bool AddRange(IEnumerable<T> t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                _DBContext.Set<T>().AddRange(t);
                int count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }
        public async Task<bool> AddRangeAsync(IEnumerable<T> t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                _DBContext.Set<T>().AddRange(t);
                int count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
                return count > 0;
            }
        }
        public bool Delete(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                _DBContext.Set<T>().Remove(t);
                int count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }

        public async Task<bool> DeleteAsync(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                _DBContext.Set<T>().Remove(t);
                int count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
                return count > 0;
            }
        }

        public bool DeleteRange(IEnumerable<T> t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                _DBContext.Set<T>().RemoveRange(t);
                int count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }
        public async Task<bool> DeleteRangeAsync(IEnumerable<T> t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                _DBContext.Set<T>().RemoveRange(t);
                int count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
                return count > 0;
            }
        }

        public void Dispose()
        {
            _DBContext.Dispose();
        }

        public T Find(dynamic Id)
        {
            return _DBContext.Set<T>().Find(Id) ?? null;
        }



        public bool Update(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                var EntityModel = _DBContext.Entry<T>(t);
                _DBContext.Set<T>().Attach(t);
                EntityModel.State = EntityState.Modified;
                int Count = _DBContext.SaveChanges();
                Ts.Complete();
                return Count > 0;
            }
        }

        public async Task<bool> UpdateAsync(T t)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                var EntityModel = _DBContext.Entry<T>(t);
                _DBContext.Set<T>().Attach(t);
                EntityModel.State = EntityState.Modified;
                int Count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
                return Count > 0;
            }
        }

        /// <summary>
        /// 修改多个
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="t"></param>
        /// <returns></returns>
        public bool UpdateRange(IEnumerable<T> t)
        {
            int Count = 0;
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                if (t != null)
                {
                    foreach (var items in t)
                    {
                        var EntityModel = _DBContext.Entry(t);
                        _DBContext.Set<T>().Attach(items);
                        EntityModel.State = EntityState.Modified;
                    }

                }
                Count = _DBContext.SaveChanges();
                Ts.Complete();
            }
            return Count > 0;
        }

        public async Task<bool> UpdateRangeAsync(IEnumerable<T> t)
        {
            int Count = 0;
            using (TransactionScope Ts = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                if (t != null)
                {
                    foreach (var items in t)
                    {
                        var EntityModel = _DBContext.Entry(items);
                        _DBContext.Set<T>().Attach(items);
                        EntityModel.State = EntityState.Modified;
                    }

                }
                Count = await _DBContext.SaveChangesAsync();
                Ts.Complete();
            }
            return Count > 0;
        }

        // <summary>
        /// 多个修改条件
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="model"></param>
        /// <param name="WhereLambda"></param>
        /// <param name="ModifiedProNames"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public bool UpdateWhere(Expression<Func<T, bool>> WhereLambda, Func<T, T> UpdateLambda)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                IQueryable<T> iq = _DBContext.Set<T>().Where(WhereLambda);
                iq = iq.Where(WhereLambda);
                var data = iq.ToList();
                var list = data.Select(UpdateLambda).ToList();
                foreach (var items in list)
                {
                    var EntityModel = _DBContext.Entry(items);
                    _DBContext.Set<T>().Attach(items);
                    EntityModel.State = EntityState.Modified;
                }

                var count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }
        public async Task<bool> UpdateWhereAsync(Expression<Func<T, bool>> WhereLambda, Func<T, T> UpdateLambda)
        {
            using (TransactionScope Ts = new TransactionScope(TransactionScopeOption.Required))
            {
                IQueryable<T> iq = _DBContext.Set<T>().Where(WhereLambda);
                iq = iq.Where(WhereLambda);
                var data = iq.ToList();
                var list = data.Select(UpdateLambda).ToList();
                foreach (var items in list)
                {
                    var EntityModel = _DBContext.Entry(items);
                    _DBContext.Set<T>().Attach(items);
                    EntityModel.State = EntityState.Modified;
                }
                var count = _DBContext.SaveChanges();
                Ts.Complete();
                return count > 0;
            }
        }

        public IQueryable<T> QueryAll(Expression<Func<T, bool>>? where)
        {
            IQueryable<T> iq = (IQueryable<T>)_DBContext.Set<T>();
            if (where != null)
            {
                iq = iq.Where(where);
            }
            return iq;

        }
        public IQueryable<T> QueryAll(params Expression<Func<T, bool>>[] wheres)
        {
            IQueryable<T> iq = _DBContext.Set<T>();
            foreach (var item in wheres)
            {
                iq = iq.Where(item);
            }

            return iq;
        }

        /// <summary>
        /// 查询所有 并排序 IEnumerable
        /// </summary>
        /// <typeparam name="type"></typeparam>
        /// <param name="order"></param>
        /// <param name="isAsc"></param>
        /// <param name="wheres"></param>
        /// <returns></returns>
        public IQueryable<T> QueryAll<type>(Expression<Func<T, type>> order, bool isAsc = true, Expression<Func<T, bool>>? wheres = null)
        {
            var iq = (IQueryable<T>)QueryAll(wheres);

            return isAsc ? iq.OrderBy(order) : iq.OrderByDescending(order);
        }



        public IQueryable<T> QueryAll<type>(out int total, int skip, int take, Expression<Func<T, type>> order, bool isAce = true, Expression<Func<T, bool>>? where = null)
        {
            var iq = (IQueryable<T>)QueryAll(order, isAce, where);
            total = iq.Count();
            return iq.Skip(skip).Take(take);
        }


    }
}
